﻿using Microsoft.AspNetCore.Mvc;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.EntityFrameworkCore.Models;
using SBlogCore.AuthorizeServe.Dtos;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using NuGet.Packaging;
using Velusia.Server.Helpers;
using static OpenIddict.Abstractions.OpenIddictConstants;

namespace SBlogCore.AuthorizeServe.Controllers.Apis
{
    //[Authorize(Roles = "")]
    [Route("api/[Controller]")]
    [ApiController]
    public class ApplicationsManagerController : Controller
    {
        private readonly OpenIddictApplicationManager<OpenIddictEntityFrameworkCoreApplication> _appManager;

        public ApplicationsManagerController( OpenIddictApplicationManager<OpenIddictEntityFrameworkCoreApplication> appManager)
        {
            _appManager = appManager;
        }
        [HttpGet]
        public async Task<List<OpenIddictEntityFrameworkCoreApplication>> GetAppList()
        {
            var appList = await _appManager.ListAsync(0, 10).ToListAsync();
            return appList;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<OpenIddictEntityFrameworkCoreApplication?> GetAppInfo(string id)
        {
            var app = await _appManager.FindByClientIdAsync(id);
            if (app == null)
                throw new Exception($"未找到ClientId为{id}的资源或程序");
            return app;
        }
        /// <summary>
        /// 注册APP
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<object> CreateApp(ApplicationsManagerInPut inPut)
        {
            var bytes = new byte[32];
            RandomNumberGenerator.Fill(bytes);
            var clientSecret = Microsoft.AspNetCore.Authentication.Base64UrlTextEncoder.Encode(bytes);
            var app = new OpenIddictApplicationDescriptor
            {
                ClientId = inPut.ClientId,
                ClientSecret = clientSecret,
                ConsentType = ConsentTypes.Explicit,
                DisplayName = inPut.DisplayName,
                RedirectUris =
                {
                    new Uri(inPut.RedirectUris)
                },
                PostLogoutRedirectUris =
                {
                    new Uri(inPut.PostLogoutRedirectUris)
                },
                Permissions =
                {
                    Permissions.Endpoints.Authorization,
                    Permissions.Endpoints.Logout,
                    Permissions.Endpoints.Token,
                    Permissions.GrantTypes.AuthorizationCode,
                    Permissions.ResponseTypes.Code,
                    Permissions.Scopes.Email,
                    Permissions.Scopes.Profile,
                    Permissions.Scopes.Roles
                },
                Requirements =
                {
                    Requirements.Features.ProofKeyForCodeExchange
                }
            };
            var res = await _appManager.CreateAsync(app);
            return new
            {
                res.ClientId,
                res.ClientSecret,
                res.DisplayName
            };
        }
        /// <summary>
        /// 修改APP
        /// </summary>
        /// <param name="inPut"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<IActionResult> UpdateApp(ApplicationsManagerInPut inPut)
        {
            if (string.IsNullOrEmpty(inPut.ClientId))
                throw new Exception("ID不能为空");
            var res = await _appManager.FindByClientIdAsync(inPut.ClientId);

            if (res == null)
                throw new Exception($"未找到ClientId为{inPut.ClientId}的资源或程序");
            var app = new OpenIddictApplicationDescriptor
            {
                ClientId = res.ClientId,
                ClientSecret = res.ClientSecret,
                ConsentType = res.ConsentType,
                DisplayName = inPut.DisplayName,
                Type = res.Type,
                RedirectUris =
                {
                    new Uri(inPut.RedirectUris)
                },
                PostLogoutRedirectUris =
                {
                    new Uri(inPut.PostLogoutRedirectUris)
                },
                Requirements =
                {
                    Requirements.Features.ProofKeyForCodeExchange
                }
            };
            app.Properties.AddRange(await _appManager.GetPropertiesAsync(res));
            app.Permissions.AddRange(await _appManager.GetPermissionsAsync(res));
            await _appManager.UpdateAsync(res, app);
            return Ok("ok");
        }
        /// <summary>
        /// 删除APP
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteApp(string id)
        {
            var app = await _appManager.FindByClientIdAsync(id);
            if (app == null)
                throw new Exception($"未找到ClientId为{id}的资源或程序");
            await _appManager.DeleteAsync(app);
            return Ok("ok");
        }
    }
}
